package com.basin.common.core.response;

import com.alibaba.fastjson2.JSON;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Getter;

import java.io.Serial;
import java.io.Serializable;

/**
 * 统一响应对象
 *
 * @author: Sam ZHONG | sammy1997@aliyun.com
 */
@Getter
@JsonInclude(JsonInclude.Include.NON_NULL)
public final class Resp<T> implements Serializable {
    @Serial
    private static final long serialVersionUID = 1L;

    private Resp() {
    }

    private Resp(int code, String message) {
        this.code = code;
        this.message = message;
    }

    private Resp(RespCodeEnum respCodeEnum) {
        this.code = respCodeEnum.getCode();
        this.message = respCodeEnum.getMessage();
    }

    private int code;

    private String message;

    private T data;

    private void setData(T data) {
        this.data = data;
    }

    private void setMessage(String message) {
        this.message = message;
    }

    private void setCode(int code) {
        this.code = code;
    }

    private static <T> Resp<T> init(boolean isSuccess) {
        return isSuccess ? new Resp<>(RespCodeEnum.SUCCESS) : new Resp<>(RespCodeEnum.FAILURE);
    }

    public static <T> Resp<T> success() {
        return Resp.init(true);
    }

    public static <T> Resp<T> fail() {
        return Resp.init(false);
    }

    public static <T> Resp<T> custom(RespCodeEnum respCodeEnum) {
        return new Resp<>(respCodeEnum);
    }

    public static <T> Resp<T> custom(RespCodeEnum respCodeEnum, T data) {
        Resp<T> resp = new Resp<>(respCodeEnum);
        resp.setData(data);
        return resp;
    }

    public static <T> Resp<T> success(String message, T data) {
        Resp<T> resp = Resp.success();
        resp.setMessage(message);
        resp.setData(data);
        return resp;
    }

    public static <T> Resp<T> success(T data) {
        Resp<T> resp = Resp.success();
        resp.setData(data);
        return resp;
    }

    public static <T> Resp<T> fail(String message) {
        Resp<T> resp = Resp.fail();
        resp.setMessage(message);
        return resp;
    }

    public static <T> Resp<T> fail(Integer code, String message) {
        Resp<T> resp = Resp.fail(message);
        resp.setCode(code);
        return resp;
    }

    @Override
    public String toString() {
        return JSON.toJSONString(this);
    }
}
